package com.example.downloadmanager;
import java.io.File;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.example.DBHelper.DBHelper;
import com.example.DBHelper.Dao;
import com.example.huashangapp.HSApplication;
import com.example.service.MainService;
import com.example.ui.learn.DownHandler;
import com.example.ui.learn.DownUtils;
import com.example.ui.learn.ListeningInfo;
import com.example.ui.leftmenu.DownItem;
import com.example.ui.leftmenu.Item02View;
import com.example.ui.leftmenu.Itme10View;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
public class Downloader<Params> {
	public String urlstr;// 下载的地址
	private String localfile;// 保存路径
	private int threadcount;// 线程数
	private DownHandler mHandler;// 消息处理器
	public static Dao dao;// 工具类
	public  int fileSize;// 所要下载的文件的大小
	public List<DownloadInfo> infos = new ArrayList<DownloadInfo>();// 存放下载信息类的集合
	private static final int INIT = 1;// 定义三种下载的状态：初始化状态，正在下载状态，暂停状态
	private static final int DOWNLOADING = 2;
	private static final int PAUSE = 3;
	private static final int DELETE = 4;
	private int state = INIT;
	private File file;
	ListeningInfo listen;
	public Downloader(String urlstr, String localfile, int threadcount,
			Context context,DownHandler mHandler) {
		this.urlstr = urlstr;
		this.localfile = localfile;
		this.threadcount = threadcount;
		this.mHandler=mHandler;
		file = new File(localfile+urlstr.substring(urlstr.lastIndexOf("/") + 1));
		dao = HSApplication.getDao();
	}

	/**
	 * 判断是否正在下载
	 */
	public boolean isdownloading() {
		return state == DOWNLOADING;
	}

	/**
	 * 得到downloader里的信息 首先进行判断是否是第一次下载，如果是第一次就要进行初始化，并将下载器的信息保存到数据库中
	 * 如果不是第一次下载，那就要从数据库中读出之前下载的信息（起始位置，结束为止，文件大小等），并将下载信息返回给下载器
	 */
	public void getDownloaderInfors() {
				if (isFirst(urlstr)) {
					Log.i("msg","是否执行getDownloaderInfors()方法");
					int range = fileSize / threadcount;
					
					for (int i = 0; i < threadcount - 1; i++) {
						DownloadInfo info = new DownloadInfo(i, i * range, (i + 1)
								* range - 1, 0, urlstr);
						infos.add(info);
					}
					DownloadInfo info = new DownloadInfo(threadcount - 1,
							(threadcount - 1) * range, fileSize - 1, 0, urlstr);
					infos.add(info);
					// 保存infos中的数据到数据库
					dao.saveInfos(infos,listen);
					// 创建一个LoadInfo对象记载下载器的具体信息
				} else {
					// 得到数据库中已有的urlstr的下载器的具体信息
					infos=null; 
					infos= dao.getInfos(urlstr);
					Log.v("TAG", "not isFirst size=" + infos.size());
					int size = 0;
					int compeleteSize = 0;
					for (DownloadInfo info : infos) {
						compeleteSize += info.getCompeleteSize();
						size += info.getEndPos() - info.getStartPos() + 1;
					}
					DownUtils.listDownItem.get(urlstr).setFileSize(fileSize);
					DownUtils.listDownItem.get(urlstr).setDownLoadFileSize(compeleteSize);
				}
			}
	/**
      */
	public void init(){
		new Thread(){
			   @Override
			public void run() {
				   try {
					   	setPriority(7);
						Log.i("msg","是否执行init()方法");
						URL url = new URL(urlstr);
						HttpURLConnection connection = (HttpURLConnection) url
								.openConnection();
						connection.setConnectTimeout(5000);
						connection.setRequestMethod("GET");
						fileSize = connection.getContentLength();
						DownUtils.listDownItem.get(urlstr).setFileSize(fileSize);
						DownItem di=DownUtils.listDownItem.get(urlstr);
						listen=new ListeningInfo(urlstr,di.getPic_Url(),di.getTitle(),di.getName(),di.getTer_Id(),di.getTag(),di.getColum_Id(),di.getSub_title(),-1,di.getDownLoadFileSize(),fileSize);
						Log.i("down","初始化文件的大小"+fileSize);
						if(fileSize>0){
							Message msg=new Message();
							msg.what=1;
							down.sendMessage(msg);
						}
						if (!file.exists()) {
							file.createNewFile();
						}
						// 本地访问文件
						RandomAccessFile accessFile = new RandomAccessFile(file, "rwd");
						accessFile.setLength(fileSize);
						accessFile.close();
						connection.disconnect();
					} catch (Exception e) {
						e.printStackTrace();
					}
				super.run();
			}
		}.start();
	}
	
	Handler down=new Handler(){
		@Override
		public void handleMessage(final Message msg) {
			switch (msg.what) {
			case 1:
				getDownloaderInfors();
				download();
				break;
			}
			super.handleMessage(msg);
		}
		
	};
	
	/**
	 * 判断是否是第一次 下载
	 */
	private boolean isFirst(String urlstr) {
		return dao.isHasInfors(urlstr);
	}
	/**
	 * 114 * 利用线程开始下载数据 115
	 */
	public void download() {
		if (infos != null){
			
			for (DownloadInfo info : infos) {
				new MyThread(info.getThreadId(), info.getStartPos(),
						info.getEndPos(), info.getCompeleteSize(),
						info.getUrl(),info).start();
			}
		}
	}

	public class MyThread extends Thread {
		private int threadId;
		private int startPos;
		private int endPos;
		private int compeleteSize;
		private DownloadInfo info;
		private String urlstr;
		public MyThread(int threadId, int startPos, int endPos,
				int compeleteSize, String urlstr,DownloadInfo info) {
			this.threadId = threadId;
			this.startPos = startPos;
			this.endPos = endPos;
			this.compeleteSize = compeleteSize;
			this.urlstr = urlstr;
			this.info=info;
			
		}
		@SuppressWarnings({ "resource", "unchecked" })
		@Override
		public void run() {

			HttpURLConnection connection = null;
			RandomAccessFile randomAccessFile = null;
			InputStream is = null;
			try {
				URL url = new URL(urlstr);
				connection = (HttpURLConnection) url.openConnection();
				connection.setConnectTimeout(5000);
				connection.setRequestMethod("GET");
				DownItem di=DownUtils.listDownItem.get(urlstr);
				connection.setRequestProperty("Range", "bytes="
						+ (startPos + compeleteSize) + "-" + endPos);
				
				randomAccessFile = new RandomAccessFile(file, "rwd");
				randomAccessFile.seek(startPos + compeleteSize);
				// 将要下载的文件写到保存在保存路径下的文件中
				is = connection.getInputStream();
				byte[] buffer = new byte[4096];
				int length = -1;
				Log.i("down","从断点开始续传"+compeleteSize);
				while ((length = is.read(buffer)) != -1) {
					if(di==null){
						return;
					}
					randomAccessFile.write(buffer, 0, length);
					compeleteSize =compeleteSize+length;
					this.info.setCompeleteSize(compeleteSize);
					di.setDownLoadFileSize(di.getDownLoadFileSize()+length);
					// 用消息将下载信息传给进度条，对进度条进行更新
					Message message = new Message();
					message.what = 0;
					message.obj = urlstr;
					if (di.isPause) {
						dao.updataInfos(threadId,compeleteSize,urlstr);
						message.what = 0;
						mHandler.sendMessage(message);
						return;
					}
					if(di.getDownLoadFileSize()>=di.getFileSize()){
							message.what = 1;
							mHandler.sendMessage(message);
							dao.delete(urlstr);
							listen=new ListeningInfo(urlstr, di.getPic_Url(), di.getTitle(),di.getName(),di.getTer_Id(),di.getTag(),di.getColum_Id(),di.getSub_title(),-1,di.getFileSize(),di.getFileSize());
							Downloader.dao.saveListens(listen);
							return;
					}
					mHandler.sendMessage(message);
				}
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				try {
					is.close();
					randomAccessFile.close();
					connection.disconnect();
					Log.i("down","检查是否执行");
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		

		}
		

		@Override
		@Deprecated
		public void destroy() {
			Log.i("down","destroy()方法被执行");
			super.destroy();
		}

		@Override
		public void interrupt() {
			Log.i("down","interrupt()方法被执行");
			super.interrupt();
		}
		@Override
		public boolean isInterrupted() {
			// TODO Auto-generated method stub
			return super.isInterrupted();
		}
	}

	// 删除数据库中urlstr对应的下载器信息
	public void delete(String urlstr) {
		dao.delete(urlstr);
	}

	// 设置暂停
	public void pause() {
		state = PAUSE;
	}

	// 重置下载状态
	public void reset() {
		state = INIT;
	}
	public int getState() {
		return state;
	}

	public void setState(int state) {
		this.state = state;
	}
}
